/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package br.ufba.lasid.jitclouds.mda.datatypes;

import br.ufba.lasid.jitclouds.mda.api.EState;
import br.ufba.lasid.jitclouds.mda.api.IFailureDetector;
import br.ufba.lasid.jitclouds.mda.api.IGroupView;
import br.ufba.lasid.jitclouds.mda.api.IReplicaHandler;
import br.ufba.lasid.jitclouds.mda.api.IReplicatedVirtualMachineHandler;
import br.ufba.lasid.jitclouds.mda.utils.Utils;
import java.io.BufferedReader;
import java.net.Inet4Address;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author aliriosa
 */
public class ReplicatedXenVMHandler extends XenVMHandler implements Runnable, IReplicatedVirtualMachineHandler{

    String location = null;
    GroupView group = new GroupView();
    String drbdResource  = null;
    String localRole = null;
    String remoteRole = null;
    IFailureDetector failureDetector = null;
    
    public void start(){
        new Thread(this).start();
    }
    
    
    @Override
    public void run(){
        while(true){            
            if(localRole!= null && remoteRole != null){
                for(IReplicaHandler replica : group){
                    if(replica != this){
                        try {
//                            EState state = failureDetector.queryStatus(replica.getLocation());
//                            if(state.equals(EState.CRASHED)){
//                                System.out.println("[DEBUG] Replica " + replica + " is crashed!");
//                            }
                        } catch (Exception ex) {
                            Logger.getLogger(ReplicatedXenVMHandler.class.getName()).log(Level.SEVERE, null, ex);
                        }
                    } 
                }
            }
        }
        
    }
    public ReplicatedXenVMHandler() throws Exception{
        this.location = Inet4Address.getLocalHost().getHostAddress();
        this.group.add(this);
    }
    
    
    
    @Override
    public String getLocation() throws Exception{        
        return location;
    }    


    @Override
    public void setLocation(String location) throws Exception {
        this.location = location;        
    }

    @Override
    public String toString() {
        return getID()+"@"+location;
    }

    @Override
    public IGroupView getGroupView() {
        return group;
    }
    
    protected void updateRole() throws Exception{
       
        if(hasDRBDResource()){
            System.out.println("[DEBUG]drbdadm role " + drbdResource);
            
            Process p = Runtime.getRuntime().exec("drbdadm role " + drbdResource);
            
            BufferedReader reader = Utils.getProcessInput(p);
            
            String outString = reader.readLine();
            
                System.out.println(outString);
            
            
            if(outString != null){
                
                outString = outString.toLowerCase();
                                
                int i = outString.indexOf("/");
                
                localRole = outString.substring(0, i);
                remoteRole = outString.substring(i);
            }
        }
    }
    
    @Override
    public boolean isPrimary() throws Exception{
        System.out.println(localRole);                
        if(localRole != null) {
            return localRole.equals("primary");
        }
        return false;
    }

    @Override
    public boolean hasDRBDResource() throws Exception{
        return drbdResource != null;
    }

    @Override
    public String getDRBDResource() throws Exception{
        return drbdResource;
    }

    @Override
    public void connect(String vmid) throws Exception {
        super.connect(vmid);
         System.out.println("[DEBUG]grep drbd " + getConfigFile());
        Process p = Runtime.getRuntime().exec("grep drbd " + getConfigFile());
        
        BufferedReader reader = Utils.getProcessInput(p);
        
        String disk = reader.readLine();
        
        if(disk != null){
            int i0 = disk.indexOf(":");
            int i1 = disk.indexOf(",", i0);
            
            drbdResource = disk.substring(i0+1, i1);
            
            if(drbdResource != null){
                drbdResource = drbdResource.trim();
            }            
        }
    }

    @Override
    public void sync() throws Exception {
        this.updateRole();
        if(localRole != null && remoteRole != null){
           if(localRole.equals(remoteRole)){
               System.out.println(localRole+" "+remoteRole);
               return;
           }

           if(isPrimary()){
   //            this.checkpoint();
               System.out.println("checkpoint "+this.getID());
           }else{
   //            this.restore();
               System.out.println("restoure "+this.getID());
           }
       }
    }

    @Override
    public IFailureDetector getFailureDetector() {
        return failureDetector;
    }
    
    public void setFailureDetector(IFailureDetector fd){
        this.failureDetector = fd;
    }    
    
}
